﻿using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using PortaCapena.OdooJsonRpcClient.Attributes;
using PortaCapena.OdooJsonRpcClient.Converters;
using PortaCapena.OdooJsonRpcClient.Models;
using System;
using System.ComponentModel;
using System.Runtime.Serialization;

namespace OdooRpcClient.Model.Sale
{
    [OdooTableName("sale.order.line")]
    [JsonConverter(typeof(OdooModelConverter))]
    public class SaleOrderLineOdooModel : IOdooModel
    {

        /// <summary>
        /// OrderId
        /// Many2one
        /// required
        /// sale.order
        /// <summary>
        [JsonProperty("order_id")]
        [Description("OrderId")]
        public long OrderId { get; set; }

        /// <summary>
        /// Name
        /// Text
        /// required
        /// <summary>
        [JsonProperty("name")]
        [Description("Name")]
        public string Name { get; set; }

        /// <summary>
        /// Sequence
        /// Integer
        /// <summary>
        [JsonProperty("sequence")]
        [Description("Sequence")]
        public int? Sequence { get; set; }

        /// <summary>
        /// InvoiceLines
        /// Many2many
        /// account.move.line
        /// <summary>
        [JsonProperty("invoice_lines")]
        [Description("InvoiceLines")]
        public long[] InvoiceLines { get; set; }

        /// <summary>
        /// InvoiceStatus
        /// Selection
        /// <summary>
        [JsonProperty("invoice_status")]
        [Description("InvoiceStatus")]
        public InvoiceStatusSaleOrderLineOdooEnum? InvoiceStatus { get; set; }

        /// <summary>
        /// PriceUnit
        /// Float
        /// required
        /// <summary>
        [JsonProperty("price_unit")]
        [Description("PriceUnit")]
        public double PriceUnit { get; set; }

        /// <summary>
        /// PriceSubtotal
        /// Monetary
        /// <summary>
        [JsonProperty("price_subtotal")]
        [Description("PriceSubtotal")]
        public decimal? PriceSubtotal { get; set; }

        /// <summary>
        /// PriceTax
        /// Float
        /// <summary>
        [JsonProperty("price_tax")]
        [Description("PriceTax")]
        public double? PriceTax { get; set; }

        /// <summary>
        /// PriceTotal
        /// Monetary
        /// <summary>
        [JsonProperty("price_total")]
        [Description("PriceTotal")]
        public decimal? PriceTotal { get; set; }

        /// <summary>
        /// PriceReduce
        /// Float
        /// <summary>
        [JsonProperty("price_reduce")]
        [Description("PriceReduce")]
        public double? PriceReduce { get; set; }

        /// <summary>
        /// TaxId
        /// Many2many
        /// account.tax
        /// <summary>
        [JsonProperty("tax_id")]
        [Description("TaxId")]
        public long[] TaxId { get; set; }

        /// <summary>
        /// PriceReduceTaxinc
        /// Monetary
        /// <summary>
        [JsonProperty("price_reduce_taxinc")]
        [Description("PriceReduceTaxinc")]
        public decimal? PriceReduceTaxinc { get; set; }

        /// <summary>
        /// PriceReduceTaxexcl
        /// Monetary
        /// <summary>
        [JsonProperty("price_reduce_taxexcl")]
        [Description("PriceReduceTaxexcl")]
        public decimal? PriceReduceTaxexcl { get; set; }

        /// <summary>
        /// Discount
        /// Float
        /// <summary>
        [JsonProperty("discount")]
        [Description("Discount")]
        public double? Discount { get; set; }

        /// <summary>
        /// ProductId
        /// Many2one
        /// product.product
        /// <summary>
        [JsonProperty("product_id")]
        [Description("ProductId")]
        public long? ProductId { get; set; }

        /// <summary>
        /// ProductTemplateId
        /// Many2one
        /// product.template
        /// <summary>
        [JsonProperty("product_template_id")]
        [Description("ProductTemplateId")]
        public long? ProductTemplateId { get; set; }

        /// <summary>
        /// ProductUpdatable
        /// Boolean
        /// <summary>
        [JsonProperty("product_updatable")]
        [Description("ProductUpdatable")]
        public bool? ProductUpdatable { get; set; }

        /// <summary>
        /// ProductUomQty
        /// Float
        /// required
        /// <summary>
        [JsonProperty("product_uom_qty")]
        [Description("ProductUomQty")]
        public double ProductUomQty { get; set; }

        /// <summary>
        /// ProductUom
        /// Many2one
        /// uom.uom
        /// <summary>
        [JsonProperty("product_uom")]
        [Description("ProductUom")]
        public long? ProductUom { get; set; }

        /// <summary>
        /// ProductUomCategoryId
        /// Many2one
        /// Conversion between Units of Measure can only occur if they belong to the same category. The conversion will be made based on the ratios.
        /// uom.category
        /// <summary>
        [JsonProperty("product_uom_category_id")]
        [Description("ProductUomCategoryId")]
        public long? ProductUomCategoryId { get; set; }

        /// <summary>
        /// ProductUomReadonly
        /// Boolean
        /// <summary>
        [JsonProperty("product_uom_readonly")]
        [Description("ProductUomReadonly")]
        public bool? ProductUomReadonly { get; set; }

        /// <summary>
        /// ProductCustomAttributeValueIds
        /// One2many
        /// product.attribute.custom.value
        /// sale_order_line_id
        /// <summary>
        [JsonProperty("product_custom_attribute_value_ids")]
        [Description("ProductCustomAttributeValueIds")]
        public long[] ProductCustomAttributeValueIds { get; set; }

        /// <summary>
        /// ProductNoVariantAttributeValueIds
        /// Many2many
        /// product.template.attribute.value
        /// <summary>
        [JsonProperty("product_no_variant_attribute_value_ids")]
        [Description("ProductNoVariantAttributeValueIds")]
        public long[] ProductNoVariantAttributeValueIds { get; set; }

        /// <summary>
        /// QtyDelivered
        /// Float
        /// <summary>
        [JsonProperty("qty_delivered")]
        [Description("QtyDelivered")]
        public double? QtyDelivered { get; set; }

        /// <summary>
        /// QtyDeliveredManual
        /// Float
        /// <summary>
        [JsonProperty("qty_delivered_manual")]
        [Description("QtyDeliveredManual")]
        public double? QtyDeliveredManual { get; set; }

        /// <summary>
        /// QtyToInvoice
        /// Float
        /// <summary>
        [JsonProperty("qty_to_invoice")]
        [Description("QtyToInvoice")]
        public double? QtyToInvoice { get; set; }

        /// <summary>
        /// QtyInvoiced
        /// Float
        /// <summary>
        [JsonProperty("qty_invoiced")]
        [Description("QtyInvoiced")]
        public double? QtyInvoiced { get; set; }

        /// <summary>
        /// UntaxedAmountInvoiced
        /// Monetary
        /// <summary>
        [JsonProperty("untaxed_amount_invoiced")]
        [Description("UntaxedAmountInvoiced")]
        public decimal? UntaxedAmountInvoiced { get; set; }

        /// <summary>
        /// UntaxedAmountToInvoice
        /// Monetary
        /// <summary>
        [JsonProperty("untaxed_amount_to_invoice")]
        [Description("UntaxedAmountToInvoice")]
        public decimal? UntaxedAmountToInvoice { get; set; }

        /// <summary>
        /// SalesmanId
        /// Many2one
        /// res.users
        /// <summary>
        [JsonProperty("salesman_id")]
        [Description("SalesmanId")]
        public long? SalesmanId { get; set; }

        /// <summary>
        /// CurrencyId
        /// Many2one
        /// res.currency
        /// <summary>
        [JsonProperty("currency_id")]
        [Description("CurrencyId")]
        public long? CurrencyId { get; set; }

        /// <summary>
        /// CompanyId
        /// Many2one
        /// res.company
        /// <summary>
        [JsonProperty("company_id")]
        [Description("CompanyId")]
        public long? CompanyId { get; set; }

        /// <summary>
        /// OrderPartnerId
        /// Many2one
        /// res.partner
        /// <summary>
        [JsonProperty("order_partner_id")]
        [Description("OrderPartnerId")]
        public long? OrderPartnerId { get; set; }

        /// <summary>
        /// AnalyticTagIds
        /// Many2many
        /// account.analytic.tag
        /// <summary>
        [JsonProperty("analytic_tag_ids")]
        [Description("AnalyticTagIds")]
        public long[] AnalyticTagIds { get; set; }

        /// <summary>
        /// IsExpense
        /// Boolean
        /// Is true if the sales order line comes from an expense or a vendor bills
        /// <summary>
        [JsonProperty("is_expense")]
        [Description("IsExpense")]
        public bool? IsExpense { get; set; }

        /// <summary>
        /// IsDownpayment
        /// Boolean
        /// Down payments are made when creating invoices from a sales order. They are not copied when duplicating a sales order.
        /// <summary>
        [JsonProperty("is_downpayment")]
        [Description("IsDownpayment")]
        public bool? IsDownpayment { get; set; }

        /// <summary>
        /// State
        /// Selection
        /// <summary>
        [JsonProperty("state")]
        [Description("State")]
        public OrderStatusSaleOrderLineOdooEnum? State { get; set; }

        /// <summary>
        /// CustomerLead
        /// Float
        /// Number of days between the order confirmation and the shipping of the products to the customer
        /// required
        /// <summary>
        [JsonProperty("customer_lead")]
        [Description("CustomerLead")]
        public double CustomerLead { get; set; }

        /// <summary>
        /// DisplayType
        /// Selection
        /// Technical field for UX purpose.
        /// <summary>
        [JsonProperty("display_type")]
        [Description("DisplayType")]
        public DisplayTypeSaleOrderLineOdooEnum? DisplayType { get; set; }

        /// <summary>
        /// IsRewardLine
        /// Boolean
        /// <summary>
        [JsonProperty("is_reward_line")]
        [Description("IsRewardLine")]
        public bool? IsRewardLine { get; set; }

        /// <summary>
        /// SaleOrderOptionIds
        /// One2many
        /// sale.order.option
        /// line_id
        /// <summary>
        [JsonProperty("sale_order_option_ids")]
        [Description("SaleOrderOptionIds")]
        public long[] SaleOrderOptionIds { get; set; }

        /// <summary>
        /// IsConfigurableProduct
        /// Boolean
        /// <summary>
        [JsonProperty("is_configurable_product")]
        [Description("IsConfigurableProduct")]
        public bool? IsConfigurableProduct { get; set; }

        /// <summary>
        /// ProductTemplateAttributeValueIds
        /// Many2many
        /// product.template.attribute.value
        /// <summary>
        [JsonProperty("product_template_attribute_value_ids")]
        [Description("ProductTemplateAttributeValueIds")]
        public long[] ProductTemplateAttributeValueIds { get; set; }

        /// <summary>
        /// PurchaseLineIds
        /// One2many
        /// Purchase line generated by this Sales item on order confirmation, or when the quantity was increased.
        /// purchase.order.line
        /// sale_line_id
        /// <summary>
        [JsonProperty("purchase_line_ids")]
        [Description("PurchaseLineIds")]
        public long[] PurchaseLineIds { get; set; }

        /// <summary>
        /// PurchaseLineCount
        /// Integer
        /// <summary>
        [JsonProperty("purchase_line_count")]
        [Description("PurchaseLineCount")]
        public int? PurchaseLineCount { get; set; }

        /// <summary>
        /// ProductPackaging
        /// Many2one
        /// product.packaging
        /// <summary>
        [JsonProperty("product_packaging")]
        [Description("ProductPackaging")]
        public long? ProductPackaging { get; set; }

        /// <summary>
        /// RouteId
        /// Many2one
        /// stock.location.route
        /// <summary>
        [JsonProperty("route_id")]
        [Description("RouteId")]
        public long? RouteId { get; set; }

        /// <summary>
        /// MoveIds
        /// One2many
        /// stock.move
        /// sale_line_id
        /// <summary>
        [JsonProperty("move_ids")]
        [Description("MoveIds")]
        public long[] MoveIds { get; set; }

        /// <summary>
        /// ProductType
        /// Selection
        /// A storable product is a product for which you manage stock. The Inventory app has to be installed.
        /// A consumable product is a product for which stock is not managed.
        /// A service is a non-material product you provide.
        /// <summary>
        [JsonProperty("product_type")]
        [Description("ProductType")]
        public ProductTypeSaleOrderLineOdooEnum? ProductType { get; set; }

        /// <summary>
        /// VirtualAvailableAtDate
        /// Float
        /// <summary>
        [JsonProperty("virtual_available_at_date")]
        [Description("VirtualAvailableAtDate")]
        public double? VirtualAvailableAtDate { get; set; }

        /// <summary>
        /// ScheduledDate
        /// Datetime
        /// <summary>
        [JsonProperty("scheduled_date")]
        [Description("ScheduledDate")]
        public DateTime? ScheduledDate { get; set; }

        /// <summary>
        /// ForecastExpectedDate
        /// Datetime
        /// <summary>
        [JsonProperty("forecast_expected_date")]
        [Description("ForecastExpectedDate")]
        public DateTime? ForecastExpectedDate { get; set; }

        /// <summary>
        /// FreeQtyToday
        /// Float
        /// <summary>
        [JsonProperty("free_qty_today")]
        [Description("FreeQtyToday")]
        public double? FreeQtyToday { get; set; }

        /// <summary>
        /// QtyAvailableToday
        /// Float
        /// <summary>
        [JsonProperty("qty_available_today")]
        [Description("QtyAvailableToday")]
        public double? QtyAvailableToday { get; set; }

        /// <summary>
        /// WarehouseId
        /// Many2one
        /// stock.warehouse
        /// <summary>
        [JsonProperty("warehouse_id")]
        [Description("WarehouseId")]
        public long? WarehouseId { get; set; }

        /// <summary>
        /// QtyToDeliver
        /// Float
        /// <summary>
        [JsonProperty("qty_to_deliver")]
        [Description("QtyToDeliver")]
        public double? QtyToDeliver { get; set; }

        /// <summary>
        /// IsMto
        /// Boolean
        /// <summary>
        [JsonProperty("is_mto")]
        [Description("IsMto")]
        public bool? IsMto { get; set; }

        /// <summary>
        /// DisplayQtyWidget
        /// Boolean
        /// <summary>
        [JsonProperty("display_qty_widget")]
        [Description("DisplayQtyWidget")]
        public bool? DisplayQtyWidget { get; set; }

        /// <summary>
        /// IsDelivery
        /// Boolean
        /// <summary>
        [JsonProperty("is_delivery")]
        [Description("IsDelivery")]
        public bool? IsDelivery { get; set; }

        /// <summary>
        /// ProductQty
        /// Float
        /// <summary>
        [JsonProperty("product_qty")]
        [Description("ProductQty")]
        public double? ProductQty { get; set; }

        /// <summary>
        /// RecomputeDeliveryPrice
        /// Boolean
        /// <summary>
        [JsonProperty("recompute_delivery_price")]
        [Description("RecomputeDeliveryPrice")]
        public bool? RecomputeDeliveryPrice { get; set; }

        /// <summary>
        /// EventId
        /// Many2one
        /// Choose an event and it will automatically create a registration for this event.
        /// event.event
        /// <summary>
        [JsonProperty("event_id")]
        [Description("EventId")]
        public long? EventId { get; set; }

        /// <summary>
        /// EventTicketId
        /// Many2one
        /// Choose an event ticket and it will automatically create a registration for this event ticket.
        /// event.event.ticket
        /// <summary>
        [JsonProperty("event_ticket_id")]
        [Description("EventTicketId")]
        public long? EventTicketId { get; set; }

        /// <summary>
        /// EventOk
        /// Boolean
        /// If checked this product automatically creates an event registration at the sales order confirmation.
        /// <summary>
        [JsonProperty("event_ok")]
        [Description("EventOk")]
        public bool? EventOk { get; set; }

        /// <summary>
        /// Margin
        /// Float
        /// <summary>
        [JsonProperty("margin")]
        [Description("Margin")]
        public double? Margin { get; set; }

        /// <summary>
        /// MarginPercent
        /// Float
        /// <summary>
        [JsonProperty("margin_percent")]
        [Description("MarginPercent")]
        public double? MarginPercent { get; set; }

        /// <summary>
        /// PurchasePrice
        /// Float
        /// <summary>
        [JsonProperty("purchase_price")]
        [Description("PurchasePrice")]
        public double? PurchasePrice { get; set; }

        /// <summary>
        /// ProjectId
        /// Many2one
        /// Project generated by the sales order item
        /// project.project
        /// <summary>
        [JsonProperty("project_id")]
        [Description("ProjectId")]
        public long? ProjectId { get; set; }

        /// <summary>
        /// TaskId
        /// Many2one
        /// Task generated by the sales order item
        /// project.task
        /// <summary>
        [JsonProperty("task_id")]
        [Description("TaskId")]
        public long? TaskId { get; set; }

        /// <summary>
        /// IsService
        /// Boolean
        /// Sales Order item should generate a task and/or a project, depending on the product settings.
        /// <summary>
        [JsonProperty("is_service")]
        [Description("IsService")]
        public bool? IsService { get; set; }

        /// <summary>
        /// QtyDeliveredMethod
        /// Selection
        /// According to product configuration, the delivered quantity can be automatically computed by mechanism :
        ///     - Manual: the quantity is set manually on the line
        ///     - Analytic From expenses: the quantity is the quantity sum from posted expenses
        ///     - Timesheet: the quantity is the sum of hours recorded on tasks linked to this sale line
        ///     - Stock Moves: the quantity comes from confirmed pickings
        /// <summary>
        [JsonProperty("qty_delivered_method")]
        [Description("QtyDeliveredMethod")]
        public MethodToUpdateDeliveredQtySaleOrderLineOdooEnum? QtyDeliveredMethod { get; set; }

        /// <summary>
        /// AnalyticLineIds
        /// One2many
        /// account.analytic.line
        /// so_line
        /// <summary>
        [JsonProperty("analytic_line_ids")]
        [Description("AnalyticLineIds")]
        public long[] AnalyticLineIds { get; set; }

        /// <summary>
        /// RemainingHoursAvailable
        /// Boolean
        /// <summary>
        [JsonProperty("remaining_hours_available")]
        [Description("RemainingHoursAvailable")]
        public bool? RemainingHoursAvailable { get; set; }

        /// <summary>
        /// RemainingHours
        /// Float
        /// <summary>
        [JsonProperty("remaining_hours")]
        [Description("RemainingHours")]
        public double? RemainingHours { get; set; }

        /// <summary>
        /// Id
        /// Integer
        /// <summary>
        [JsonProperty("id")]
        [Description("Id")]
        public long Id { get; set; }

        /// <summary>
        /// DisplayName
        /// Char
        /// <summary>
        [JsonProperty("display_name")]
        [Description("DisplayName")]
        public string DisplayName { get; set; }

        /// <summary>
        /// CreateUid
        /// Many2one
        /// res.users
        /// <summary>
        [JsonProperty("create_uid")]
        [Description("CreateUid")]
        public long? CreateUid { get; set; }

        /// <summary>
        /// CreateDate
        /// Datetime
        /// <summary>
        [JsonProperty("create_date")]
        [Description("CreateDate")]
        public DateTime? CreateDate { get; set; }

        /// <summary>
        /// WriteUid
        /// Many2one
        /// res.users
        /// <summary>
        [JsonProperty("write_uid")]
        [Description("WriteUid")]
        public long? WriteUid { get; set; }

        /// <summary>
        /// WriteDate
        /// Datetime
        /// <summary>
        [JsonProperty("write_date")]
        [Description("WriteDate")]
        public DateTime? WriteDate { get; set; }

        /// <summary>
        /// LastUpdate
        /// Datetime
        /// <summary>
        [JsonProperty("__last_update")]
        [Description("LastUpdate")]
        public DateTime? LastUpdate { get; set; }
    }


    [JsonConverter(typeof(StringEnumConverter))]
    public enum InvoiceStatusSaleOrderLineOdooEnum
    {
        [EnumMember(Value = "upselling")]
        UpsellingOpportunity = 1,

        [EnumMember(Value = "invoiced")]
        FullyInvoiced = 2,

        [EnumMember(Value = "to invoice")]
        ToInvoice = 3,

        [EnumMember(Value = "no")]
        NothingToInvoice = 4,
    }


    [JsonConverter(typeof(StringEnumConverter))]
    public enum OrderStatusSaleOrderLineOdooEnum
    {
        [EnumMember(Value = "draft")]
        Quotation = 1,

        [EnumMember(Value = "sent")]
        QuotationSent = 2,

        [EnumMember(Value = "sale")]
        SalesOrder = 3,

        [EnumMember(Value = "done")]
        Locked = 4,

        [EnumMember(Value = "cancel")]
        Cancelled = 5,
    }


    // Technical field for UX purpose.
    [JsonConverter(typeof(StringEnumConverter))]
    public enum DisplayTypeSaleOrderLineOdooEnum
    {
        [EnumMember(Value = "line_section")]
        Section = 1,

        [EnumMember(Value = "line_note")]
        Note = 2,
    }


    // A storable product is a product for which you manage stock. The Inventory app has to be installed.
    // A consumable product is a product for which stock is not managed.
    // A service is a non-material product you provide.
    [JsonConverter(typeof(StringEnumConverter))]
    public enum ProductTypeSaleOrderLineOdooEnum
    {
        [EnumMember(Value = "consu")]
        Consumable = 1,

        [EnumMember(Value = "service")]
        Service = 2,

        [EnumMember(Value = "product")]
        StorableProduct = 3,
    }


    // According to product configuration, the delivered quantity can be automatically computed by mechanism :
    //   - Manual: the quantity is set manually on the line
    //   - Analytic From expenses: the quantity is the quantity sum from posted expenses
    //   - Timesheet: the quantity is the sum of hours recorded on tasks linked to this sale line
    //   - Stock Moves: the quantity comes from confirmed pickings
    // 
    [JsonConverter(typeof(StringEnumConverter))]
    public enum MethodToUpdateDeliveredQtySaleOrderLineOdooEnum
    {
        [EnumMember(Value = "manual")]
        Manual = 1,

        [EnumMember(Value = "analytic")]
        AnalyticFromExpenses = 2,

        [EnumMember(Value = "stock_move")]
        StockMoves = 3,

        [EnumMember(Value = "timesheet")]
        Timesheets = 4,
    }

}
